namespace SimpleWebServices.Web
{
    using System;
    using System.Linq;
    using System.Xml.Serialization;
    using SimpleWebServices.Configuration;

    [XmlRoot("resource")]
    public sealed class DefaultResource : Resource
    {
        public static void CopyTo(IResource resource)
        {
            if (null == resource)
            {
                throw new ArgumentNullException("resource");
            }

            if (typeof(DefaultResource).IsAssignableFrom(resource.GetType()))
            {
                /// do nothing, otherwise you are in a never-ending loop
            }
            else
            {
                CopyTo(new Default().Object<DefaultResource>(), resource);
            }
        }

        private static void CopyTo(IResource source, IResource destination)
        {
            if (null != source && null != destination)
            {
                if (!destination.Cacheability.HasValue)
                {
                    destination.Cacheability = source.Cacheability;
                }

                if (string.IsNullOrEmpty(destination.Description))
                {
                    destination.Description = source.Description;
                }

                if (string.IsNullOrEmpty(destination.Etag))
                {
                    destination.Etag = source.Etag;
                }

                if (null == destination.Expires)
                {
                    destination.Expires = source.Expires;
                }

                if (!destination.Modified.HasValue)
                {
                    destination.Modified = source.Modified;
                }

                if (!destination.Status.HasValue)
                {
                    destination.Status = source.Status;
                }

                if (string.IsNullOrEmpty(destination.Title))
                {
                    destination.Title = source.Title;
                }

                foreach (var datum in source.Data.Where(x => !destination.Data.Contains(x.Key)))
                {
                    destination.Data.Add(datum);
                }

                foreach (var link in source.Links.Where(x => !destination.Links.Contains(x)))
                {
                    destination.Links.Add(link);
                }

                foreach (var meta in source.Metadata.Where(x => !destination.Metadata.Contains(x)))
                {
                    destination.Metadata.Add(meta);
                }
            }
        }
    }
}